#ifndef __SUBSYSTEM_BED_WARS_H__
#define __SUBSYSTEM_BED_WARS_H__

#include "Subsystems/Subsystem.hpp"
#include "TeamType.h"
#include "entt/entity/entity.hpp"
#include <mutex>

namespace PocketSurvival
{
    struct ComponentPlayer;

    class SubsystemPickables;
    class SubsystemSignBlockBehavior;
    class SubsystemPlayers;

    struct ComponentChest;
    struct IInventory;
    
}



namespace BedWars
{
    class BedWarsCore;

    enum class BedWarsStatue
    {
        Prepare,        // 准备
        Countdown,      // 倒计时
        GameRunning,    // 游戏进行中
        Ending          // 结算
    };

    class SubsystemBedWars : public PocketSurvival::Subsystem
    {
    private:
        float m_gameTime;
        std::mutex m_bedHealthMutex;
        uint8_t bedHealth[4];
        std::string teamNames[4];
        bool teamSignNeedUpdate[4];
        int32_t m_lastTime = 0;
        float m_produceTime = 0.0f;

        uint32_t ironProduceCount = 0;
        uint32_t diamondProductCount = 0;

        PocketSurvival::SubsystemSignBlockBehavior *signBlockBehavior;
        PocketSurvival::SubsystemPickables *subsystemPickables;
        PocketSurvival::SubsystemPlayers *subsystemPlayers;

        bool realDead = false;
        float deadTime = 0.0f;
        float injureBaseValue = 0.0f;
        
        
    public:
        bool canRestart;

        BedWarsStatue mainStatue = BedWarsStatue::Prepare;

        BedWarsCore *bedWarsCore = nullptr;

        std::mutex m_teamMutex;
        std::unordered_map<uint16_t, TeamType> playerTeamMap;
        std::set<entt::entity> teamEntitySet[4];

    public:
        SubsystemBedWars();

        virtual void onEntityAdded(entt::entity entity) override;
        virtual void onEntityRemoved(entt::entity entity) override;

        TeamType getEntityTeam(entt::entity entity);
        bool joinTeam(entt::entity entity, TeamType ranksType);
        bool exitTeam(entt::entity entity);

        void setTeamClothes(PocketSurvival::ComponentPlayer *componentPlayer, TeamType teamType);
        void addBaseTools(PocketSurvival::ComponentPlayer *componentPlayer);
        void resetPlayer(PocketSurvival::ComponentPlayer *componentPlayer);
        void toTeamHomePosition(PocketSurvival::ComponentPlayer *componentPlayer);

        uint32_t getTeamPlayerCount(TeamType teamType);

        void teamClear();
        void terrainClear();
        void teamZeroPlayerClear(TeamType teamType);

        // 获取队伍的人数
        uint8_t getTeamHealth(TeamType teamType);
        // 队伍的墓碑被破坏了一次
        uint8_t decTeamHealth(TeamType teamType);
        const std::string &getTeamName(TeamType teamType);

        void changeStatue(BedWarsStatue statue);
        void produceSourcePickable(uint32_t count);
        bool transaction(PocketSurvival::ComponentChest *chest, uint32_t chestIndex, PocketSurvival::IInventory *inventory, uint32_t slotIndex);

        virtual const std::string& getName() const override;
        virtual void update(float dt) override;
        virtual void load(const nlohmann::json& json) override;
        virtual PocketSurvival::SubLoadEchelon getLoadEchelon() override;
        virtual PocketSurvival::SubUpdateType getUpdateType() override;

    };

    // 获取队伍墓碑剩余的破坏次数
    inline uint8_t SubsystemBedWars::getTeamHealth(TeamType teamType)
    {
        std::lock_guard<std::mutex> lk(m_bedHealthMutex);
        return bedHealth[(uint8_t)teamType];
    }
    
} // namespace BedWars

#endif
